package com.tonicgb.shared.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tonicgb.shared.common.constants.Constants;
import com.tonicgb.shared.common.enums.MessageCodeEnum;
import com.tonicgb.shared.core.jwt.contracts.JWTSubject;
import com.tonicgb.shared.exception.ApiException;

import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhaiyujin
 * @date 2021-09-03 15:01:55
 * @说明 jwt 应用类
 */
public class JWTUtil {


    //密钥
    private static final String SECRET = "TonicGB" ;
    private static final int EXPIRATION_M=60;

    /**
     * 生成token
     * @return
     * @throws Exception
     */
    public static String createToken(JWTSubject user) throws Exception{

        //签发时间
        Date iatDate=new Date();
        //过期时间-outTime分钟过期
        Calendar nowTime= Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, Constants.TOKEN_EXPRESS_MINUTES);
        Date expiresDate=nowTime.getTime();


        Map<String,Object> map=new HashMap<String,Object>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        ObjectMapper mapper = new ObjectMapper();
        String token="";
        //创建token
        token= JWT.create()
                .withHeader(map)
                .withClaim("id",user.JWTIdentifier())
                .withClaim("userType",user.JWTCustomClaims().getCode())
                .withExpiresAt(expiresDate)//设置过期时间-过期时间要大于签发时间
                .withIssuedAt(iatDate)//设置签发时间
                .sign(Algorithm.HMAC256(SECRET));//加密
        return token;
    }

    /**
     * 解密token
     * @param token
     * @return
     * @throws Exception
     */
    public static void verifyToken(String token) throws ApiException {
        JWTVerifier verifier= null;
        DecodedJWT jwt=null;
        try {

             verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt=verifier.verify(token);
        }catch (JWTVerificationException e){
            throw new ApiException(MessageCodeEnum.JWTExpiredError);
        }catch (ApiException e) {
            throw new ApiException(MessageCodeEnum.JWTValidError);
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
            throw new ApiException(e.getMessage());
        }


    }


    /**
     * 只获取claims
     * @param token
     * @return
     */
    public static Map<String, Claim> getClaims(String  token){
        DecodedJWT jwt=null;
        jwt= JWT.decode(token);
        Map<String, Claim> o=    jwt.getClaims();
          return jwt.getClaims();
    }

}
